#ifndef ___SKELETON_H__
#define ___SKELETON_H__

#include <OGF/cells/common/common.h>
#include <OGF/cells/map/map.h>
#include <OGF/cells/map/map_attributes.h>

#include <OGF/basic/types/counted.h>
#include <OGF/math/attributes/attribute_adapter.h>
#include <OGF/surface/grob/surface.h>

//#include <OGF/math/linear_algebra/sparse_matrix.h>
#include <OGF/math/linear_algebra/vector.h>
#include <OGF/math/linear_algebra/matrix.h>
#include <OGF/math/geometry/types.h>
#include <OGF/cells/map/geometry.h>

#include <OGF/cells/graph/graph_editor.h>
#include <OGF/cells/graph/graph_attributes.h>
#include <OGF/scene_graph/types/scene_graph.h>
#include <OGF/surface/grob/line.h>
#include <OGF/quick_start/common/simplify.h>

#include <string>
#include <vector>
#include <set>
#include <iostream>

namespace OGF {

class Skeleton
{

public:
	Skeleton();
	~Skeleton();
	void lazy_init(Surface*);
	void init(Surface*);
	void extract_iteration(Surface*);	
	void simplify(int);
	void simplifySingleStep();
	void initializeSimplifier(Surface*);
	void super_iteration();
	void setFeatureSize();
	Line* getSkeleton() { return skeleton; }


private:
	double get_cotan_weight(Map::Halfedge* he);
	void calculate_cotan_weights();
	double calc_local_area(Map::Vertex *v);
	bool isDegenerateVertex(Map::Vertex *v);
	bool isFullyDegenerateVertex(Map::Vertex *v);
	Line* extractSkeletonGraph();



	Surface *surface;
	Line *skeleton;
	Simplify *simplifier;			// Skeleton simplifier
	LinearSolver *solver;	
	double WL;				// Contraction Weight
	double WH_0; 				// Initial shape matching weight
	double Aavg;				// Average model face area
	MapVertexAttribute<int> *index;		// Index of vertices
	double MAX_CONTRACTION_SQUARED;
	double MAX_ATTRACTION;
	double MIN_COT_ANGLE;
	int CONTRACTION_SCALE;



};




}  //namespace
#endif // ___SKELETON_H__
